///////////////////////////////////////////////////////////
///////////////// Have an itch? Scratch it! ///////////////
///////////////////////// SCRATCH /////////////////////////
/////////////////////  A MUD  Server   ////////////////////
///////////////////// By: Jared Devall ////////////////////
/////////////////////      Thanks:     ////////////////////
/////////////////////  DIKU/Merc/ROM   ////////////////////
///////////////////// Aetas/Deus Gang  ////////////////////
/////////////////////       Beej       ////////////////////
///////////////////////////////////////////////////////////

#include "definitions.h"
#include <list>
#include "commands.h"
#include "commandTable.h"
#include "character.h"
#include "world.h"
#include "stringutil.h"
#include "split.h"
#include "timestamp.h"
#include "functions.h"
#include "logs.h"
#include "vEditHandler.h"
#include "object.h"

using namespace std;

// Command definitions for commands beginning with the letters A through F
// (Keep in alphabetical order... it's MUCH easier)
CmdAedit::CmdAedit() {
	SetName( "aedit" );
	SetLevel( GOD );
	SetEnabled( true );
	SetOmniset( true );
}

bool CmdAedit::Execute( Character* c, const string& args ) {
	
	c->SetStatus( AEDIT );
	c->Send( "Welcome to Symphony Edit Mode (SEM) for Areas!\n\rFor a list of available commands in aedit mode, type \"commands\"\n\r" );

	return true;
}

CmdAlist::CmdAlist() {
	SetName( "alist" );
	SetLevel( 1 );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdAlist::Execute( Character* c, const string& args ) {
	std::string buf;
	std::list< Area* >::iterator it;
	int i = 0;

	if ( args.empty() ) {
		for ( it = World::Instance().getAreas().begin(); it != World::Instance().getAreas().end(); it++, i++ ) {
			buf << " [" << i+1 << "] ";
			if ( i < 10 )
				buf << "  ";
			if ( i < 100 )
				buf << " ";
			if ( c->getLevel() >= BUILDER ) {
				buf << (*it)->GetFirstv() << " - " << (*it)->GetLastv();
				if ( i == 0 )
					buf << '\t';
				buf << '\t';
			}
			buf << (*it)->GetName() << '\n';
		}
	} else {
		for ( it = World::Instance().getAreas().begin(); it != World::Instance().getAreas().end(); it++, i++ )
			if ( sub_str( args, (*it)->GetName() ) ) {
				buf << " [" << i+1 << "] ";
				if ( i < 10 )
					buf << "  ";
				if ( i < 100 )
					buf << " ";
				if ( c->getLevel() >= BUILDER ) {
					buf << (*it)->GetFirstv() << " - " << (*it)->GetLastv();
					if ( i == 0 )
						buf << '\t';
					buf << '\t';
				}
				buf << (*it)->GetName() << '\n';
			}
	}

	c->Send( buf );

	return true;
}

CmdAsave::CmdAsave() {
	SetName( "asave" );
	SetLevel( BUILDER );
	SetEnabled( true );
	SetOmniset( true );
}

bool CmdAsave::Execute( Character* c, const string& args ) {
	std::string buf;

	World::Instance().Save();
	buf << "World data saved " << Timestamp::Instance().GetDateTime() << "\n\r";
	c->Send( buf );

	return true;
}

CmdBoards::CmdBoards() {
	SetName( "boards" );
	SetLevel( 1 );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdBoards::Execute( Character* c, const string& args ) {
	std::string buf;
	std::string tmp;
	std::string arg1, arg2;
	std::string syntax;
	std::list< Board* >::iterator b_it;
	std::list< Note* >::iterator n_it;
	int i = 0;

	syntax =  "syntax: boards                lists all boards\n\r";
	syntax << "        board <number>        selects a board\n\r";
	syntax << "        board list            lists all posts on the currently selected board\n\r";
	syntax << "        board read <number>   read a note on the currently selected board\n\r";

	split( args, arg1, arg2 );

	if ( arg1.empty() ) {
		buf << "\t{!WBoards{x\n\r\n\r";
		for ( b_it = World::Instance().getBoards().begin(); b_it != World::Instance().getBoards().end(); b_it++ ) {
			buf << format( 2, (*b_it)->getNumber(), tmp, 'Y' ) << ": ";
			if ( c->getBoard() == (*b_it) )
				buf << sFormat( 10, (*b_it)->getName(), tmp, "@y" );
			else
				buf << format( 10, (*b_it)->getName(), tmp, 'y' );
			buf << " ({g" << (*b_it)->getNotes().size() << "{x)\n\r";
		}
	} else if ( arg1 == "list" ) {
		if ( c->getBoard() == 0 ) {
			c->Send( "You must select a board first.\n\r" );
			return false;
		} else {
			for ( n_it = c->getBoard()->getNotes().begin(); n_it != c->getBoard()->getNotes().end(); n_it++ ) {
				buf << format( 4, (*n_it)->getId(), tmp, 'Y' );
				buf << format( 20, (*n_it)->getAuthor(), tmp, 'y' ) << " [ {R";
				buf << (*n_it)->getSubject() << "{x ]\n\r";
			}
		}
	} else if ( arg1 == "read" ) {
		if ( c->getBoard() == 0 ) {
			c->Send( "You must select a board first.\n\r" );
			return false;
		} else {
			int note = atoi( arg2.c_str() );
			for ( n_it = c->getBoard()->getNotes().begin(); n_it != c->getBoard()->getNotes().end(); n_it++ )
				if ( (*n_it)->getId() == note ) {
					buf << "Author:    {C" << (*n_it)->getAuthor() << "{x\n\r";
					buf << "Recipient: {C" << (*n_it)->getRecipient() << "{x\n\r";
					buf << "Subject:   {C" << (*n_it)->getSubject() << "{x\n\r";
					buf << "Sent:      {C" << (*n_it)->getSent() << "{x\n\r\n\r";
					buf << (*n_it)->getBody() << "\n\r";
				}
		}
	} else {
		i = atoi( args.c_str() );
		for ( b_it = World::Instance().getBoards().begin(); b_it != World::Instance().getBoards().end(); b_it++ ) {
			if ( (*b_it)->getNumber() == i ) {
				c->setBoard( *b_it );
				buf << "You've selected the " << c->getBoard()->getName() << " board.\n\r";
				break;
			}
		}
		if ( c->getBoard() == 0 ) {
			c->Send( "Invalid board number.\n\r" );
			return false;
		}
	}


	if ( buf.empty() ) {
		c->Send( syntax );
		return false;
	}

	c->Send( buf );

	return true;
}

CmdBuzz::CmdBuzz( ) {
	SetName( "buzz" );
	SetLevel( BUILDER );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdBuzz::Execute( Character* c, const string &args ) {
	string name;
	string arg;
	string message;
	Character* target;
	
	split( args, name, arg );
	if ( ( target = World::Instance().FindCharacter( name ) ) == NULL ) {
		c->Send( "That target cannot be found.\n\r" );
		return false;
	};
	message << "\n\r\a{RYou have been buzzed by {W" << c->getName() << "{R!{x";
	target->Send( message );
	c->Send( "Your target has been buzzed!\n\r" );
	return true;
}

CmdClose::CmdClose() {
	SetName( "close" );
	SetLevel( 1 );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdClose::Execute( Character* c, const string& args ) {
	string buf;

	if ( args.empty() ) {
		c->Send( "Which door do you wish to close?\n\r" );
		return true;
	}

	if ( strcmp( args.c_str(), "north" ) == 0 || strcmp( args.c_str(), "n" ) == 0 ) {
		if ( !c->getRoom()->GetExit( NORTH ).GetThere() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( NORTH ).GetDoor() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( NORTH ).GetOpen() ) {
			c->Send( "That door is already closed.\n\r" );
			return true;
		}
		c->getRoom()->GetExit( NORTH ).SetOpen( false );
		World::Instance().FindRoom( c->getRoom()->GetExit( NORTH ).GetPoint() )->GetExit( SOUTH ).SetOpen( false );
		c->Send( "You have closed the door.\n\r" );
		return true;
	}
	if ( strcmp( args.c_str(), "east" ) == 0 || strcmp( args.c_str(), "e" ) == 0 ) {
		if ( !c->getRoom()->GetExit( EAST ).GetThere() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( EAST ).GetDoor() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( EAST ).GetOpen() ) {
			c->Send( "That door is already closed.\n\r" );
			return true;
		}
		c->getRoom()->GetExit( EAST ).SetOpen( false );
		World::Instance().FindRoom( c->getRoom()->GetExit( EAST ).GetPoint() )->GetExit( WEST ).SetOpen( false );
		c->Send( "You have closed the door.\n\r" );
		return true;
	}
	if ( strcmp( args.c_str(), "south" ) == 0 || strcmp( args.c_str(), "s" ) == 0 ) {
		if ( !c->getRoom()->GetExit( SOUTH ).GetThere() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( SOUTH ).GetDoor() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( SOUTH ).GetOpen() ) {
			c->Send( "That door is already closed.\n\r" );
			return true;
		}
		c->getRoom()->GetExit( SOUTH ).SetOpen( false );
		World::Instance().FindRoom( c->getRoom()->GetExit( SOUTH ).GetPoint() )->GetExit( NORTH ).SetOpen( false );
		c->Send( "You have closed the door.\n\r" );
		return true;
	}
	if ( strcmp( args.c_str(), "west" ) == 0 || strcmp( args.c_str(), "w" ) == 0 ) {
		if ( !c->getRoom()->GetExit( WEST ).GetThere() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( WEST ).GetDoor() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( WEST ).GetOpen() ) {
			c->Send( "That door is already closed.\n\r" );
			return true;
		}
		c->getRoom()->GetExit( WEST ).SetOpen( false );
		World::Instance().FindRoom( c->getRoom()->GetExit( WEST ).GetPoint() )->GetExit( EAST ).SetOpen( false );
		c->Send( "You have closed the door.\n\r" );
		return true;
	}
	if ( strcmp( args.c_str(), "up" ) == 0 || strcmp( args.c_str(), "u" ) == 0 ) {
		if ( !c->getRoom()->GetExit( UP ).GetThere() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( UP ).GetDoor() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( UP ).GetOpen() ) {
			c->Send( "That door is already closed.\n\r" );
			return true;
		}
		c->getRoom()->GetExit( UP ).SetOpen( false );
		World::Instance().FindRoom( c->getRoom()->GetExit( UP ).GetPoint() )->GetExit( DOWN ).SetOpen( false );
		c->Send( "You have closed the door.\n\r" );
		return true;
	}
	if ( strcmp( args.c_str(), "down" ) == 0 || strcmp( args.c_str(), "d" ) == 0 ) {
		if ( !c->getRoom()->GetExit( DOWN ).GetThere() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( DOWN ).GetDoor() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( DOWN ).GetOpen() ) {
			c->Send( "That door is already closed.\n\r" );
			return true;
		}
		c->getRoom()->GetExit( DOWN ).SetOpen( false );
		World::Instance().FindRoom( c->getRoom()->GetExit( DOWN ).GetPoint() )->GetExit( UP ).SetOpen( false );
		c->Send( "You have closed the door.\n\r" );
		return true;
	}
	return true;
}

CmdColors::CmdColors() {
	SetName( "colors" );
	SetLevel( 1 );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdColors::Execute( Character* c, const string& args ) {
	std::string buf;

	buf << "Color table:\n\r";
	buf << "\t{{r  -{rdark red\n\r";
	buf << "\t{{R  -{Rbright red\n\r";
	buf << "\t{{g  -{gdark green\n\r";
	buf << "\t{{G  -{Gbright green\n\r";
	buf << "\t{{b  -{bdark blue\n\r";
	buf << "\t{{B  -{Bbright blue\n\r";
	buf << "\t{{y  -{ydark yellow/brown\n\r";
	buf << "\t{{Y  -{Ybright yellow\n\r";
	buf << "\t{{m  -{mdark magenta\n\r";
	buf << "\t{{M  -{Mbright magenta\n\r";
	buf << "\t{{c  -{cdark cyan\n\r";
	buf << "\t{{C  -{Cbright cyan\n\r";
	buf << "\t{{w  -{wdark grey/black\n\r";
	buf << "\t{{W  -{Wwhite\n\r";
	buf << "\t{{x  -{xdefault\n\r";

	c->Send( buf );
	return true;
}

CmdCommands::CmdCommands( ) {
	SetName( "commands" );
	SetLevel( 1 );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdCommands::Execute( Character* c, const string &args ) {
	std::string buf;
	std::string temp;
	list< Command* >::iterator it;
	int f = 0;

	if ( c->getLevel() >= HEAD ) {
		buf << "\n\r\t{chead (level " << HEAD << ") commands:{x\n\r";
		for ( it = CommandTable::Instance()._commands.begin(); it != CommandTable::Instance()._commands.end(); ++it ) {
			if ( (*it)->_level == HEAD ) {
				if ( !(*it)->_enabled )
					buf << "{w";
				if ( f == 0 ) {
					buf << "  " << (*it)->_name.c_str() << spaces( 12, (*it)->_name.c_str(), temp );
				} else {
					buf << (*it)->_name.c_str() << spaces( 12, (*it)->_name.c_str(), temp );
				}
				if ( !(*it)->_enabled )
					buf << "{x";
			    f++;
			    if ( f == 5 ) {
					buf << "\n\r";
					f = 0;
				}
			}
		}
	}
	if ( f != 0 && f != 5 )
		buf << "\n\r";
	f = 0;
	if ( c->getLevel() >= GOD ) {
		buf << "\n\r\t{cgod (level " << GOD << ") commands:{x\n\r";
		for ( it = CommandTable::Instance()._commands.begin(); it != CommandTable::Instance()._commands.end(); ++it ) {
			if ( (*it)->_level == GOD ) {
				if ( !(*it)->_enabled )
					buf << "{w";
				if ( f == 0 ) {
					buf << "  " << (*it)->_name.c_str() << spaces( 12, (*it)->_name.c_str(), temp );
				} else {
					buf << (*it)->_name.c_str() << spaces( 12, (*it)->_name.c_str(), temp );
				}
				if ( !(*it)->_enabled )
					buf << "{x";
			    f++;
			    if ( f == 5 ) {
					buf << "\n\r";
					f = 0;
				}
			}
		}
	}
	if ( f != 0 && f != 5 )
		buf << "\n\r";
	f = 0;
	if ( c->getLevel() >= BUILDER ) {
		buf << "\n\r\t{cbuilder (level " << BUILDER << ") commands:{x\n\r";
		for ( it = CommandTable::Instance()._commands.begin(); it != CommandTable::Instance()._commands.end(); ++it ) {
			if ( (*it)->_level == BUILDER ) {
				if ( !(*it)->_enabled )
					buf << "{w";
				if ( f == 0 ) {
					buf << "  " << (*it)->_name.c_str() << spaces( 12, (*it)->_name.c_str(), temp );
				} else {
					buf << (*it)->_name.c_str() << spaces( 12, (*it)->_name.c_str(), temp );
				}
				if ( !(*it)->_enabled )
					buf << "{x";
			    f++;
			    if ( f == 5 ) {
					buf << "\n\r";
					f = 0;
				}
			}
		}
	}
	if ( f != 0 && f != 5 )
		buf << "\n\r";
	f = 0;
	buf << "\n\r\t{c-- Commands --{x \n\r";
	for ( it = CommandTable::Instance()._commands.begin(); it != CommandTable::Instance()._commands.end(); ++it ) {
		if ( (*it)->_level == 1 ) {
			if ( !(*it)->_enabled )
				buf << "{w";
			if ( f == 0 ) {
				buf << "  " << (*it)->_name.c_str() << spaces( 12, (*it)->_name.c_str(), temp );
			} else {
				buf << (*it)->_name.c_str() << spaces( 12, (*it)->_name.c_str(), temp );
			}
			if ( !(*it)->_enabled )
				buf << "{x";
			   f++;
			   if ( f == 5 ) {
				buf << "\n\r";
				f = 0;
			}
		}
	}
	if ( f != 0 && f != 5 )
		buf << "\n\r";

	c->Send( buf );

	return true;
}

CmdDemote::CmdDemote() {
	SetName( "demote" );
	SetLevel( GOD );
	SetEnabled( true );
	SetOmniset( true );
}

bool CmdDemote::Execute( Character* c, const string& args ) {
	std::string buf;
	std::string buf2;
	std::string name;
	std::string sLevel;
	int level = 0;
	Character* target = 0;

	split( args, name, sLevel );

	if ( name.empty() || sLevel.empty() ) {
		c->Send( " >> \"demote\" decreases a characters' level.\n\rsyntax: promote <character name> <level>\n\r" );
		return false;
	}

	level = atoi( sLevel.c_str() );
	if ( ( target = World::Instance().FindCharacter( name ) ) == NULL ) {
		c->Send( "That target cannot be found.\n\r" );
		return false;
	}

	if ( target->getLevel() <= level ) {
		c->Send( "That wouldn't be a demotion.\n\r" );
		return false;
	}

	if ( c->getLevel() <= target->getLevel() + 2 || c->getLevel() <= level + 2 ) {
		c->Send( "You do not have permission to do that.\n\r" );
		return false;
	}

	target->setLevel( level );

	buf << "You have demoted " << target->getName() << " to level " << target->getLevel() << "!\n\r";
	buf2 << c->getName() << " has {Rdemoted{x you to level {w" << target->getLevel() << "{x!\n\r";

	c->Send( buf );
	target->Send( buf2 );

	return true;
}

CmdDescription::CmdDescription() {
	SetName( "description" );
	SetLevel( 1 );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdDescription::Execute( Character* c, const string& args ) {
	std::string buf;

	c->setVEdit( true );
	vEditList::Instance().act( c, args );

	return true;
}

CmdDisable::CmdDisable() {
	SetName( "disable" );
	SetLevel( HEAD );
	SetEnabled( true );
	SetOmniset( true );
}

bool CmdDisable::Execute( Character* c, const string& args ) {
	std::string buf;
	std::string command;
	bool found = false;
	Command* comm = 0;

	if ( args.empty() ) {
		c->Send( " >> \"disable\" disables a command from use.\n\r\n\rsyntax: disable <command name>\n\r" );
		return true;
	}

	command = args;

	for ( std::list< Command* >::iterator it = CommandTable::Instance()._commands.begin(); it != CommandTable::Instance()._commands.end(); it++ ) {
		comm = *it;
		if ( comm->_name == command ) {
			if ( comm->_level == HEAD ) {
				buf << "Level " << HEAD << " commands cannot be disabled.\n\r";
				break;
			}
			if ( !comm->_enabled )
				buf << comm->_name << " is already disabled.\n\r";
			else {
				// Disable the command...
				comm->_enabled = false;
				buf << comm->_name << " has been disabled.\n\r";
				// Log the event...
				std::string log1;
				std::string log2;
				log1 << "disabled the command \"" << comm->_name << "\"";
				log2 << c->getName() << " disabled the command \"" << comm->_name << "\"";
				log( c->getName(), c->getLevel(), log1 );
				log( WORLD, log2 );
			}
			found = true;
		}
	}

	if ( !found )
		c->Send( "That command was not found.\n\r" );

	c->Send( buf );

	return true;
}

CmdDisconnect::CmdDisconnect( ) {
	SetName( "disconnect" );
	SetLevel( GOD );
	SetEnabled( true );
	SetOmniset( true );
}

bool CmdDisconnect::Execute( Character* c, const string& args ) {
	string starget;
	string arguments;
	Character* target;
	
	if ( args.empty() ) {
		c->Send( "Syntax: disconnect <player>\n\r" );
		return false;
	}
	
	split ( args, starget, arguments );
	
	if ( ( target = World::Instance().FindCharacter( starget ) ) == NULL ) {
		c->Send( "That target cannot be found.\n\r" );
		return false;
	}

	target->SetDisconnected( true );
	c->Send( "Your target has been disconnected.\n\r" );

	return true;
}

CmdDown::CmdDown() {
	SetName( "down" );
	SetLevel( 1 );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdDown::Execute( Character* c, const string& args ) {
	std::string buf;
	std::string fromMessage;
	std::string toMessage;
	Exit* in = &( c->getRoom()->GetExit( DOWN ) );
	
	if ( !in->GetThere() ) {
		buf << "There is no exit that way.\n";
		c->Send( buf );
		return true;
	}
	else if ( in->GetDoor() && !in->GetOpen() ) {
		buf << "That door is closed.\n";
		c->Send( buf );
		return true;
	}
	else {
		Room* from = c->getRoom();
		Room* to = 0;
		if ( ( to = World::Instance().FindRoom( in->GetPoint() ) ) == NULL ) {
			c->Send( "You can't go there.\n\r" );
			std::string message = "Exit inconsistency: ";
			message << from->GetVnum() << " down to " << in->GetPoint();
			log( SERVER, message );
			return false;
		}

		fromMessage << c->getName() << " has left going down.";
		toMessage << c->getName() << " has arrived from above.";

		from->Remove( c );
		sendToRoom( from, fromMessage );
		sendToRoom( to, toMessage );
		to->Add( c );
		from->Remove( c );
		c->setRoom( World::Instance().FindRoom( to->GetVnum() )->GetVnum() );
		CmdLook Command;
		Command.Execute( c, "auto_look: down" );
	}

	return true;
}

CmdDrop::CmdDrop() {
	SetName( "drop" );
	SetLevel( 1 );	
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdDrop::Execute( Character* c, const string& args ) {
	std::string buf;

	if ( args == "all" ) {
		std::string buf2;
		for ( std::list< Object* >::iterator it = c->getInventory().begin(); c->getInventory().size() != 0; it = c->getInventory().begin() ) {
			c->remove( *it );
			c->getRoom()->Add( *it );
			buf2 << "\n\r" << c->getName() << " drops " << (*it)->getShort() << "{x.";
			buf << "You drop " << (*it)->getShort() << "{x.\n\r";
		}
		sendToRoom( c->getRoom(), buf2 );
		c->Send( buf );
		return true;
	}

	for ( std::list< Object* >::iterator it = c->getInventory().begin(); it != c->getInventory().end(); it++ )
		if ( args == (*it)->getKeywords() || sub_str( args, (*it)->getKeywords() ) ) {
			c->remove( *it );
			c->getRoom()->Add( *it );
			buf << c->getName() << " drops " << (*it)->getShort() << "{x.";
			sendToRoom( c->getRoom(), buf );
			buf = "You drop ";
			buf << (*it)->getShort() << "{x.\n\r";
			c->Send( buf );
			return true;
		}

	c->Send( "You don't have that item.\n\r" );

	return false;
}

CmdEast::CmdEast() {
	SetName( "east" );
	SetLevel( 1 );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdEast::Execute( Character* c, const string& args ) {
	std::string buf;
	std::string fromMessage;
	std::string toMessage;
	Exit* in = &( c->getRoom()->GetExit( EAST ) );
	
	if ( !in->GetThere() ) {
		buf << "There is no exit that way.\n";
		c->Send( buf );
		return true;
	}
	else if ( in->GetDoor() && !in->GetOpen() ) {
		buf << "That door is closed.\n";
		c->Send( buf );
		return true;
	}
	else {
		Room* from = c->getRoom();
		Room* to = 0;
		if ( ( to = World::Instance().FindRoom( in->GetPoint() ) ) == NULL ) {
			c->Send( "You can't go there.\n\r" );
			std::string message = "Exit inconsistency: ";
			message << from->GetVnum() << " east to " << in->GetPoint();
			log( SERVER, message );
			return false;
		}

		fromMessage << c->getName() << " has left to the east.";
		toMessage << c->getName() << " has arrived from the west.";

		from->Remove( c );
		sendToRoom( from, fromMessage );
		sendToRoom( to, toMessage );
		to->Add( c );
		from->Remove( c );
		c->setRoom( World::Instance().FindRoom( to->GetVnum() )->GetVnum() );
		CmdLook command;
		command.Execute( c, "auto_look: east" );
	}

	return true;
}

CmdEat::CmdEat() {
	SetName( "eat" );
	SetLevel( BUILDER );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdEat::Execute( Character* c, const string& args ) {
	std::string buf;
	std::string roomBuf;
	std::string name = args;
	Mob* mob = 0;
	Object* obj = 0;

	if ( args.empty() ) {
		c->Send( "syntax: CmdEat <mob name | object name>\n\r" );
		return false;
	}

	// Check mobs...
	for ( int i = 0; i < (int)c->getRoom()->getMlist().size(); i++ )
		if ( c->getRoom()->getM( i )->getName() == name || str_prefix( name, c->getRoom()->getM( i )->getName() ) ) {
			mob = c->getRoom()->getM( i );
			c->getRoom()->Remove( mob );
			World::Instance().getMlist().remove( mob );
			buf << "\"" << mob->getShort() << "\" destroyed.\n\r";
			roomBuf << c->getName() << " has destroyed " << mob->getShort() << ".";
			sendToRoom( c->getRoom(), roomBuf );
			delete mob;
			mob = 0;
			c->Send( buf );
			return true;
		}

	// Check objects...
	for ( int i = 0; i < (int)c->getRoom()->getOlist().size(); i++ )
		if ( c->getRoom()->getO( i )->getKeywords() == name || str_prefix( name, c->getRoom()->getO( i )->getKeywords() ) ) {
			obj = c->getRoom()->getO( i );
			c->getRoom()->Remove( obj );
			World::Instance().getOlist().remove( obj );
			buf << "\"" << obj->getShort() << "\" destroyed.\n\r";
			roomBuf << c->getName() << " has destroyed " << obj->getShort() << ".";
			sendToRoom( c->getRoom(), roomBuf );
			delete obj;
			obj = 0;
			c->Send( buf );
			return true;
		}

	c->Send( "Target not found.\n\r" );

	return false;
}

CmdEmote::CmdEmote( ) {
	SetName( "emote" );
	SetLevel( 1 );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdEmote::Execute( Character* c, const string &args ) {
	string buf;
	char buf2[MAX_BUFFER];

	if ( args.empty() ) {
		c->Send( "What do you wish to emote?\n\r" );
		return true;
	}

	if ( args[0] != ',' && args[0] != '\'' ) {
		buf2[0] = ' ';
	    strcpy( buf2+1, args.c_str() );
    } else {
	   strcpy( buf2, args.c_str() );
    }

	 buf << c->getName() << buf2 << "\n\r";

	World::Instance().Broadcast( buf, WCONNECTED );
	return true;
}

CmdEnable::CmdEnable() {
	SetName( "enable" );
	SetLevel( HEAD );
	SetEnabled( true );
	SetOmniset( true );
}

bool CmdEnable::Execute( Character* c, const string& args ) {
	std::string buf;
	std::string command;
	bool found = false;
	Command* comm = 0;

	if ( args.empty() ) {
		c->Send( " >> \"enable\" enables a disabled command.\n\r\n\rsyntax: enable <command name>\n\r" );
		return true;
	}

	command = args;

	for ( std::list< Command* >::iterator it = CommandTable::Instance()._commands.begin(); it != CommandTable::Instance()._commands.end(); it++ ) {
		comm = *it;
		if ( comm->_name == command ) {
			if ( comm->_enabled )
				buf << comm->_name << " is already enabled.\n\r";
			else {
				// Enable the command...
				comm->_enabled = true;
				buf << comm->_name << " has been enabled.\n\r";
				// Log the event...
				std::string log1;
				std::string log2;
				log1 << "enabled the command \"" << comm->_name << "\"";
				log2 << c->getName() << " enabled the command \"" << comm->_name << "\"";
				log( c->getName(), c->getLevel(), log1 );
				log( WORLD, log2 );
			}
			found = true;
		}
	}

	if ( !found )
		buf << "That command was not found.\n\r";

	c->Send( buf );

	return true;
}
